package com.fhzn.boss.mapper;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fhzn.boss.entity.Resource;
import com.fhzn.boss.enums.Constants;
import com.fhzn.boss.web.converter.ResourceConverter;
import com.fhzn.boss.web.request.ResourceQueryRequest;
import com.fhzn.boss.web.vo.ResourceExportVO;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 老顾
 * @apiNote
 * @since 2023/12/20
 */
public interface ResourceMapper extends BaseMapper<Resource> {

    /**
     * 分页查询资源
     *
     * @param request 请求参数
     * @return 返回参数
     */
    default Page<Resource> getResourcesByPage(ResourceQueryRequest request) {
        LambdaQueryWrapper<Resource> resourceWrapper = Wrappers.lambdaQuery();
        resourceWrapper.orderByDesc(Resource::getUpdatedTime);
        if (request.getName() != null && !request.getName().isEmpty()) {
            resourceWrapper.like(Resource::getName, request.getName());
        }
        if (request.getCode() != null && !request.getCode().isEmpty()) {
            resourceWrapper.eq(Resource::getCode, request.getCode());
        }
        if (request.getResourceType() != null && request.getResourceType() != 0) {
            resourceWrapper.eq(Resource::getResourceType, request.getResourceType());
        }
        if (request.getLevel() != null) {
            resourceWrapper.eq(Resource::getLevel, request.getLevel());
        }
        if (request.getParentCode() != null && !request.getParentCode().isEmpty()) {
            resourceWrapper.eq(Resource::getParentCode, request.getParentCode());
        }
        if (request.getStatus() != null) {
            resourceWrapper.eq(Resource::getStatus, request.getStatus());
        }
        if (request.getAppCode() != null && !request.getAppCode().isEmpty()) {
            resourceWrapper.eq(Resource::getAppCode, request.getAppCode());
        } else {
            resourceWrapper.eq(Resource::getAppCode, Constants.APP_CODE);
        }
        if (request.getSort() != null) {
            resourceWrapper.eq(Resource::getSort, request.getSort());
        }
        return selectPage(Page.of(request.getPage(), request.getPageSize()), resourceWrapper);
    }

    /**
     * 根据 code 和 appCode 查询资源
     *
     * @param code    资源code
     * @param appCode 应用code
     * @return 返回资源
     */
    default Resource getResourceByCodeAndAppCode(String code, String appCode) {
        LambdaQueryWrapper<Resource> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Resource::getId, Resource::getName, Resource::getCode, Resource::getParentCode,
                        Resource::getResourceUrl, Resource::getLevel, Resource::getResourceType, Resource::getSort,
                        Resource::getComment, Resource::getStatus, Resource::getAppCode,
                        Resource::getCreator, Resource::getModifier, Resource::getCreatedTime, Resource::getUpdatedTime)
                .eq(Resource::getCode, code)
                .eq(Resource::getAppCode, appCode);
        return selectOne(queryWrapper);
    }

    /**
     * 根据应用code查询资源列表
     *
     * @param invokeAppName 应用code
     * @return 返回资源列表
     */
    default List<Resource> findResourcesByAppCode(String invokeAppName) {
        LambdaQueryWrapper<Resource> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(Resource::getAppCode, invokeAppName);
        wrapper.eq(Resource::getStatus, 1);
        return selectList(wrapper);
    }

    /**
     * 根据应用code查询资源列表
     *
     * @param code 应用code
     * @return 返回资源列表
     */
    default List<ResourceExportVO> findByAppCode(String code) {
        List<Resource> resources = selectList(Wrappers.lambdaQuery(Resource.class)
                .eq(Resource::getAppCode, code))
                .stream()
                .sorted(Comparator.comparingInt(Resource::getLevel)
                        .thenComparing(Resource::getParentCode, Comparator.nullsFirst(String::compareTo))
                        .thenComparing(Resource::getCode, Comparator.nullsFirst(String::compareTo)))
                .collect(Collectors.toList());

        return ResourceConverter.convertResourceToVoList(resources);
    }

    /**
     * 根据code和appCode查询资源
     *
     * @param code    资源code
     * @param appCode 应用code
     * @return 返回资源
     */
    default Resource findByCodeAndAppCode(String code, String appCode) {
        return selectOne(Wrappers.lambdaQuery(Resource.class)
                .eq(Resource::getCode, code)
                .eq(Resource::getAppCode, appCode));
    }
}
